/*
 * @Author: your name
 * @Date: 2021-04-02 18:57:41
 * @LastEditTime: 2021-04-07 14:51:02
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \deepexi-system-digital-retail-consolee:\v3-ts\src\utils\digital\index.ts
 */
type ASMD = 'add' | 'subtract' | 'multiply' | 'divide';

/**
 * @description: 创建一个数字四则运算的基类
 * @author: 颜锦忠
 */
class BasicCalc {
  public power: number;
  constructor() {
    this.power = 0;
  }
  /**
   * @description: 处理传递过来的数值，获取其小数点后面的长度
   * @param {Array} rest - 传递过来的参数数组
   * @return {Array} 返回数组内的数字小数点后面的长度
   * @author: 颜锦忠
   */
  private transform(rest: number[]): number[] {
    const res = rest.map((item) => {
      /** 将循环遍历获取的数据转成字符串，再根据.分割成数组 */
      const i = item.toString().split('.');
      /** 长度大于1即说明有小数点，直接返回第二个值得长度，反之则是没有小数点那就是0 */
      return i.length > 1 ? i[1].length : 0;
    });
    return res;
  }
  /**
   * @description: 获取对应类型的平方值
   * @param {number} rest - 传递过来的数组
   * @param {ASMD} type - 传递过来的类型
   * @return {number} 平方值
   * @author: 颜锦忠
   */
  square(rest: number[], type: ASMD): number {
    switch (type) {
      case 'add':
      case 'subtract':
        this.power = this.transform(rest).reduce((a, b) => {
          return Math.pow(10, Math.max(a, b));
        });
        break;
      case 'multiply':
        this.power = this.transform(rest).reduce((a, b) => a + b);
        break;
      case 'divide':
        this.power = this.transform(rest).reduce((a, b) => b - a);
        break;
      default:
        this.power = 0;
        break;
    }
    return this.power;
  }

  /**
   * @description: 进行乘除运算前的处理，先将小数点去掉再计算
   * @param {number} rest - 传递过来的参数数组
   * @param {ASMD} type - 类型 - 区分乘除
   * @return {number} 返回对应的运算结果
   * @author: 颜锦忠
   */
  md(rest: number[], type: ASMD): number {
    const value: number[] = rest.map((item) => +item.toString().replace('.', ''));
    const res = value.reduce((a, b): number => {
      if (type === 'multiply') return a * b;
      if (type === 'divide') return a / b;
      return 0;
    });
    return res;
  }
}

/**
 * @description:继承运算基类来构建四则运算
 * @author: 颜锦忠
 */
class Calculate extends BasicCalc {
  constructor() {
    super();
  }
  /**
   * @description: 四则-加减法运算
   * @description: 加法正常传值,减法则是被减的那个数传负值，即前面加多一个-号运算符
   * @param {array} rest - 传递过来的参数数组
   * @return {number} 返回加减法运算后的结果
   * @author: 颜锦忠
   */
  add(...rest: number[]): number {
    /** 调用基类的方法获取次方值 */
    super.square(rest, 'add');
    const res =
      rest.reduce((a, b) => {
        return a * this.power + b * this.power;
      }) / this.power;
    return res;
  }

  /**
   * @description: 乘法运算
   * @param {array} rest - 参数数组
   * @return {number} 运算结果
   * @author: 颜锦忠
   */
  multiply(...rest: number[]): number {
    /** 调用基类的方法获取次方值 */
    super.square(rest, 'multiply');
    const res = super.md(rest, 'multiply') / Math.pow(10, this.power);
    return res;
  }
  /**
   * @description: 除法运算
   * @param {array} rest - 参数数组
   * @return {number} 运算结果
   * @author: 颜锦忠
   */
  divide(...rest: number[]): number {
    /** 调用基类的方法获取次方值 */
    super.square(rest, 'divide');
    const res = super.md(rest, 'divide') * Math.pow(10, this.power);
    return res;
  }
}

export default new Calculate();
